from socket import *
import time,json
import yaml
import threading,struct,os
from threading import Thread

now = int(time.time())
timeArray = time.localtime(now)
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
log_name="%s.log"%otherStyleTime
if os.path.exists(log_name):
    os.remove(log_name)

def log_print(*args, **kwargs):
    lis=[str(x) for x in args]
    msgs=" ".join(lis)
    print(msgs)
    with open(log_name, 'a+') as f:
        f.write(msgs+"\n")  #文件的写操作
def elog_print(*args, **kwargs):
    lis=[str(x) for x in args]
    msgs=" ".join(lis)
    print(msgs)
    with open("error_"+log_name, 'a+') as f:
        f.write(msgs+"\n")  #文件的写操作
def hex_to_bytes(hex_str):
    """
    :param hex_str: 16进制字符串
    :return: byte_data 字节流数据
    """
    bytes_data = bytes()
    while hex_str :
        """16进制字符串转换为字节流"""
        temp = hex_str[0:2]
        s = int(temp, 16)
        bytes_data += struct.pack('B', s)
        hex_str = hex_str[2:]
    return bytes_data

# 读取Yaml文件方法
def read_yaml(yaml_path):
    with open(yaml_path, encoding="utf-8", mode="r") as f:
        result = yaml.load(stream=f,Loader=yaml.FullLoader)
        return result

class MySocket(Thread):
    def __init__(self,config):
        super().__init__()
        # 2.准备连接服务器，建立连接
        self.serve_ip = config["serve_ip"]#当前"118.24.111,149"
        self.serve_port = config["serve_port"]  #端口当前7900
        self.sleep_time = config["sleep_time"]
        print("connect to ： ",self.serve_ip,self.serve_port)
        self.reconnect_time=9
        self.lock = threading.RLock()
        self.try_connnet()

    def check_connection(self):
        try:
            self.tcp_socket.getpeername()
            return True
        except Exception as e:
            return False
    def try_connnet(self):
        connect=False
        try:
            self.lock.acquire()
            self.tcp_socket.close()
            self.lock.release()
        except Exception as e:
            print("尝试关闭socket")

        while not connect:
            try:
                self.tcp_socket = socket(AF_INET,SOCK_STREAM)
                self.tcp_socket.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1) #在客户端开启心跳维护
                self.tcp_socket.connect((self.serve_ip,self.serve_port))  # 连接服务器，建立连接,参数是元组形式
                
				
                json_data={  
					"timestamp": int(time.time()*1000),#时间戳放大一位和格式要求的长度保持一致
					"type":"HEARBEAT"
                }
				#log_print( json_data)
                message = json.dumps(json_data)
                data='{:08X}'.format(len(message))+message.encode('utf-8').hex().upper()
                data=hex_to_bytes(data)
				#进行定时发送
                self.send_msg(data)
                connect=True
            except Exception as e:
                print(e, " 休眠%s秒后重试！！！！"%self.reconnect_time)
                time.sleep(self.reconnect_time)
        print("重新连接上socket")
    #定时发送信息
    def run(self):
        while True:
            #message=input('You can say:')
            #json标注的模板
            json_data={  
                "timestamp": int(time.time()*1000),#时间戳放大一位和格式要求的长度保持一致
                "type":"HEARBEAT"
            }
            #print( json_data)
            message = json.dumps(json_data)
            data='{:08X}'.format(len(message))+message.encode('utf-8').hex().upper()
            data=hex_to_bytes(data)

            #进行定时发送
            self.send_msg(data)
            # self.lock.acquire()
            # self.tcp_socket.send(data)#将发送的数据进行编码
            # self.lock.release()
            try:
                #进行定时发送
                self.lock.acquire()
                a=self.tcp_socket.recv(1024)#接受服务端的信息，最大数据为1k
                self.lock.release()
                time.sleep(self.sleep_time)
                print(a.decode('utf-8'))
            except Exception as e:
                self.try_connnet()
                print('重连网络连接！！！！！')
        print("线程运行结束。。。。。")


    def send_msg(self,msg):
        if self.check_connection() is False:
            print('服务器掉线！！！！！')
            self.try_connnet()  # 连接服务器，建立连接,参数是元组形式
        try:
            #进行定时发送
            self.lock.acquire()
            self.tcp_socket.send(msg)
            print(msg)
            self.lock.release()
        except Exception as e:
            self.try_connnet()
            print('重连网络连接！！！！！')

if "__main__"==__name__:
    #进行定时通信测试
    config=read_yaml("config.yaml")
    socket_client=MySocket(config)
    socket_client.start()

#cd D:\实战项目\游戏状态识别